/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.elcom.util;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;

/**
 *
 * @author GiangLT
 */
public class SequenceGenerator {

    private static AtomicInteger sequence;

    static {
        File sequenceFile = new File(Constant.CONFIG_FOLDER + "sequence.seq");
        if (!sequenceFile.exists()) {
            try {
                FileUtils.write(sequenceFile, "0");
            } catch (Exception ex) {
                Logger.getLogger(SequenceGenerator.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        try {
            sequence = new AtomicInteger(Integer.parseInt(FileUtils.readFileToString(sequenceFile)));
        } catch (IOException ex) {
            Logger.getLogger(SequenceGenerator.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public static synchronized int getNextSequence() {
        if (sequence.get() == Integer.MAX_VALUE) {
            sequence.set(0);
        }
        int result = sequence.getAndIncrement();

        try {
            RandomAccessFile file = new RandomAccessFile(Constant.CONFIG_FOLDER + "sequence.seq", "rws");
            FileChannel channel = file.getChannel();
            FileLock lock = channel.lock();
            file.seek(0);
            file.setLength(0);
            file.write(String.valueOf(result).getBytes());
            lock.release();
            file.close();            
            channel.close();
        } catch (IOException ex) {
            Logger.getLogger(SequenceGenerator.class.getName()).log(Level.SEVERE, null, ex);
        }

        return result;

    }

    public static void main(String[] args) {
        Executor e = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 1000; i++) {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    System.out.println(SequenceGenerator.getNextSequence());
                }
            };
            e.execute(r);
        }
    }
}
